#pragma once
#include <iostream>
#include <unistd.h>
#include <time.h>
#include <string>
#include <sstream>
#include <fstream>
#include <functional>
#include<memory>
#include "Mutex.hpp"

using namespace MutexModule;

namespace LogModule
{
    // 抽象类 回调执行方法即多态
    class LogVirtual
    {
    public:
        virtual ~LogVirtual() = default;
        virtual void Refreshpolicy(std::string message) = 0;
    };

    // 控制台刷新策略
    class ConsoleLogPolicy : public LogVirtual
    {
    public:
        ConsoleLogPolicy() {}
        ~ConsoleLogPolicy() {}

        void Refreshpolicy(std::string message) override
        {
            LockGuard lock(_mutex);
            std::cout << message << std::endl;
        }

    private:
        Mutex _mutex; // 保持输出不重叠
    };

    // 文件刷新策略
    class FileLogPolicy : public LogVirtual
    {
    public:
        FileLogPolicy() {}
        ~FileLogPolicy() {}

        void Refreshpolicy(std::string message) override
        {
            LockGuard lock(_mutex);
            // 定义日志目录和文件名

            std::ofstream file("LOG.txt", std::ios_base::app);
            if (file.is_open())
            {
                file << message << std::endl;
                file.close();
            }
            else
            {
                std::cerr << "open " << "LOG.txt"<< "error" << std::endl;
            }
        }

    private:
        Mutex _mutex; // 保持输出不重叠
    };

    // 获取当前时间 2025-08-04 15:03:20
    std::string GetCurrentTime()
    {
        time_t cur_time = time(nullptr);
        struct tm *p = localtime(&cur_time);

        char buffer[1024];
        int n = snprintf(buffer, sizeof(buffer) - 1, "%4d-%02d-%02d %02d:%02d:%02d", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
        buffer[n] = 0;

        return buffer;
    }

    enum LogLevel
    {
        DEBUG,
        INFOMATION, // 普通信息
        WARNING,
        ERROR, // 错误
        FATAL, // 致命的
    };

    std::string GetLevel(enum LogLevel le)
    {
        switch (le)
        {
        case DEBUG:
            return "DEBUG";
            break;
        case INFOMATION:
            return "INFOMATION";
            break;
        case WARNING:
            return "WARNING";
            break;
        case ERROR:
            return "ERROR";
            break;
        case FATAL:
            return "FATAL";
            break;
        default:
            "NONE";
            break;
        }

        return "NONE";
    }

    class Log
    {
    private:
        class Message
        {
        public:
            Message(std::string level, std::string name, std::string line,std::shared_ptr<LogVirtual> logRefresh)
                : _level(level), _name(name), _line(line),_logRefresh(logRefresh)
            {
                _curtime = GetCurrentTime();
                _pid = std::to_string(getpid());

                // 析构时打印文字
                char buffer[1024];
                int n = snprintf(buffer, sizeof(buffer) - 1, "[%s] [%s] [%s] [%s] [%s]:",
                                 _curtime.c_str(),
                                 _level.c_str(), _pid.c_str(), _name.c_str(), _line.c_str());
                buffer[n] = 0;
                _ostr+=buffer;
            }

            ~Message()
            {
                _logRefresh->Refreshpolicy(_ostr);
            }

            template <class T>
            Message &operator<<(T info)
            {
                std::ostringstream _ostream;
                _ostream << info;
                _ostr+=_ostream.str();
                return *this;
            }

            // [2025-08-04 15:03:20] [INFO] [206234] [文件名] [行号] 信息
        private:
            std::string _pid;
            std::string _curtime;
            std::string _level;
            std::string _name;
            std::string _line;
            //std::ostringstream _ostream;
            std::string _ostr;
            std::shared_ptr<LogVirtual> _logRefresh;//打印方式
        };

    public:
        Log()
        {
            _logRefresh = std::make_shared<ConsoleLogPolicy>();
        }
        ~Log() {}

        void FileRefresh()
        {
            _logRefresh = std::make_shared<FileLogPolicy>();
        }
        void ConsoleRefresh()
        {
            _logRefresh = std::make_shared<ConsoleLogPolicy>();
        }

        //Message 要在前面定义或者声明否则找不到
        Message operator()(std::string level, std::string name, std::string line)
        {
            return Message(level, name, line,_logRefresh);
        }
    private:
        std::shared_ptr<LogVirtual> _logRefresh;
    };
}

LogModule::Log logger;
#define LOG(level) logger(GetLevel(level), __FILE__, std::to_string(__LINE__))
#define LOG_CONSOLE() logger.ConsoleRefresh()
#define LOG_FILE() logger.FileRefresh()
